import {
  Base64
} from './base64';
import {
  socketBaseUrl, envVersion
} from './config'
import {
  Uint8Array2HexStr
} from './util'

export const Web_Socket = new class {

  constructor() {
    console.log("==>new WebSocket class")
    this.connect = false;
    this.linkPwdCode = 0x0011
  }
  storageKey = {
    csm_token: 'csm_token',
    deviceKey: 'deviceKey',
    visitor_token: 'visitor_token'
  }
  heartCheck = {
    timeout: 10000, 
    timeoutObj: null,
    serverTimeoutObj: null,
    //清除定时器
    reset: function () {
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      return this;
    },
    start: function (sendFunc, closeFunc) {
       //  发送约定好的信息
      this.timeoutObj = setTimeout(()=> {
         sendFunc()
         //连接WebSocket
        this.serverTimeoutObj = setTimeout(() =>{
          closeFunc()
        }, this.timeout);
      }, this.timeout);
    },
    close: function() {
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
    }
  }
  
  connectSocket(url) {
    console.log('===>', socketBaseUrl + url)
    return wx.connectSocket({
      url: socketBaseUrl + url,
      header: {
        'content-type': 'application/json'
      },
      success() {}
    })
  }

  buildSocket(eventName) {
    if (eventName) {
      this.eventName = eventName;
    }
    console.log('==>', {
      connect: this.connect
    })
    if (!this.connect) {
      this.build();
    }
  }

  async build() {
    const sessionKey = wx.getStorageSync('szm_token').userId;
    if (!sessionKey) {
      console.error('==>未登录不开启websocket')
      return false;
    }
    console.log('==> socket onOpen before')
    this.$socket = this.connectSocket(`/${sessionKey}/${wx.getStorageSync('uuid')}`)
    this.$socket.onOpen(res => {
      console.log('==>socket onOpen ', res)
      this.connect = true;
    })

    this.$socket.onClose(res => {
      console.log('==>socket onClose ', res)
      this.connect = false;
      this.heartCheck.close();
    })

    this.$socket.onError(res => {
      console.log('==>socket onError ', res)
      this.connect = false;
    })

    this.$socket.onMessage(res => {
      if(envVersion !== "develop") {
        this.heartCheck.reset().start(
          () => this.$socket?.send({data: "ping"}), 
          () => {
            this.$socket?.close();
            this.connect = false;
          });
      }
      console.log('==>socket onMessage ', res)
      this.connect = true;
      // {"deviceKey":"G6quL6ACXiF2ZKK3IvhR","kvMap":{"0":"AQ==","3":"dk1RWFJnUXI="}}
      if (res && res.data && !/code/.test(res.data)) {
        const r = JSON.parse(res.data)
        const {
          kvMap,
          deviceKey
        } = r;
        const codes = Object.keys(kvMap);
        codes.forEach(k => kvMap[k] = Base64.base64DecToArr(kvMap[k]));
        codes.forEach(i => console.log(`${this.eventName}页面 ${deviceKey}<=应答`, `指令Hex[${parseInt(i).toString(16).toUpperCase().padStart(4, '0')}]`, `值Hex[${Uint8Array2HexStr(kvMap[i], ',')}]`))
        // this[`sorket_call`](kvMap)
        if (codes.find(c => parseInt(c) === this.linkPwdCode)) {
          wx.setStorageSync('link_pwd_' + deviceKey, [...kvMap[this.linkPwdCode]])
        }
        wx.$eventEmitter.emit("showLoading", 0);
        wx.$eventEmitter.emit(this.eventName || "socket", {
          kvMap,
          deviceKey
        });
      }
    })
  }

}();